package com.darco.darcoapp;

import static DARCOShared.utils.Constants.*;

import java.lang.reflect.Method;

import org.bouncycastle.asn1.x509.sigi.PersonalData;

import DARCOShared.requests.LoginRequest;
import DARCOShared.responses.LoginResponse;
import DARCOShared.responses.ResponseBase;
import DARCOShared.responses.ResponseWrapper;
import DARCOShared.utils.MD5;
import DARCOShared.utils.MachineSpecificConstants;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import com.darco.darcoapp.db.DarcoData;

import eneter.messaging.endpoints.typedmessages.TypedResponseReceivedEventArgs;


public class Login_Activity extends MessagingActivity implements OnClickListener {

	private boolean goToTest = false;
	private MessagingManager mm;
	private DarcoData darco_db;
	ContentValues account= null;	//data support
	ContentValues system= null;
	private boolean automaticLogin=false;

	@Override
	protected void onStart() {
		super.onStart();

	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login_);

		//precompilazione campi
		if(MachineSpecificConstants.precompileLoginFields){
			EditText emailedit = (EditText)(findViewById(R.id.login_email_editText));
			emailedit.setText("test001@gmail.com");
			EditText passedit = (EditText)(findViewById(R.id.login_password_editText));
			passedit.setText("test001");
		}
		
		//resctict
		try{	
			Class strictModeClass=Class.forName("android.os.StrictMode");
			Class strictModeThreadPolicyClass=Class.forName("android.os.StrictMode$ThreadPolicy");
			Object laxPolicy = strictModeThreadPolicyClass.getField("LAX").get(null);
			Method method_setThreadPolicy = strictModeClass.getMethod("setThreadPolicy", strictModeThreadPolicyClass );
			method_setThreadPolicy.invoke(null,laxPolicy);
		} catch (Exception e) {e.printStackTrace();

		}
		//recupero il db
		darco_db= new DarcoData(this);

		//verifico il caso di logout o back da main
		Intent i=getIntent();
		if(i!=null && i.getExtras()!=null){
			boolean close = i.getExtras().getBoolean("CLOSE_IMMEDIATELY",false);
			boolean logout = i.getExtras().getBoolean("MENU_LOGOUT",false); 
			if (close==true){
				finish();} // non usata
			if(logout==true && darco_db!=null){
				//devo cancellare tutte le informazioni salvate nel database
				darco_db.deleteAll(TABLE_NAME_ACCOUNTS);
				darco_db.deleteAll(TABLE_NAME_SYSTEM);
				darco_db.deleteAll(TABLE_NAME_TRADES);
				darco_db.deleteAll(TABLE_NAME_UNIQUECARDS);
				if(account!=null)
					account.clear();
				else
					account = new ContentValues();

				if (system!=null)
					system.clear();
				else
					system = new ContentValues();
			}
		}

		//click listener for all buttons
		View access_button = findViewById(R.id.login_access_button);
		access_button.setOnClickListener(this);

		View createAccount_button = findViewById(R.id.login_create_button);
		createAccount_button.setOnClickListener(this);

		View test_button = findViewById(R.id.login_test_button);
		test_button.setOnClickListener(this);

		findViewById(R.id.login_loginandtest_button).setOnClickListener(this);
		//get the informations from the db about the system

		if(account==null){ //è la prima volta che è stata visualizzata Login_activity

			ContentValues systemData = darco_db.getSystemData();
			ContentValues accountInfo = darco_db.getAccountInfo();

			if(accountInfo!=null && systemData!=null){	
				//salvo la mail salvata in account
				String emailSystem	=	systemData.getAsString(SYSTEM_SAVEDACCOUNT);
				String emailAccount	= 	accountInfo.getAsString(ACCOUNT_EMAIL);

				if(		emailSystem.matches(EMAIL_PATTERN) && 
						emailAccount.matches(EMAIL_PATTERN) && 
						emailSystem.compareTo(emailAccount)==0)
				{
					showLoadingDialog("Login with "+emailAccount);
					account=accountInfo; //uso le informazioni prese dal db
					system=systemData;
					
					automaticLogin=true;
					account.put("ACCOUNT_REMEMBER", true);
					LoginRequest login_req= new LoginRequest(emailAccount,account.getAsString(ACCOUNT_PASSWORD));
					onPerformRequest(login_req);
					
					/*
					Intent i2 = new Intent(this,Main_Activity.class);
					i2.putExtra("account",account);
					i2.putExtra("system",system);
					startActivity(i2);
					*/
				}


			}
		}


	}

	private void performLoginRequest(){
		account= new ContentValues();
		system= new ContentValues();

		account.put(ACCOUNT_EMAIL,((EditText) findViewById(R.id.login_email_editText)).getText().toString().replace(" ",""));
		account.put(ACCOUNT_PASSWORD,MD5.get(((EditText) findViewById(R.id.login_password_editText)).getText().toString()));	

		String email=account.getAsString(ACCOUNT_EMAIL);
		if(!email.matches(EMAIL_PATTERN)){
			Toast.makeText(this, email +" non e' una mail valida", Toast.LENGTH_LONG).show();
		}

		View remember= findViewById(R.id.login_remember_checkBox);
		Boolean rem = ((CheckBox) remember).isChecked();

		account.put("ACCOUNT_REMEMBER", rem);

		String pwdMD5 = account.getAsString(ACCOUNT_PASSWORD);
		//richiesta al server con
		LoginRequest login_req= new LoginRequest(email,pwdMD5);
		onPerformRequest(login_req);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_login_, menu);
		return true;
	}

	@Override
	public void onClick(View arg0) {
		switch(arg0.getId()){
		case R.id.login_create_button:
			Intent i1 = new Intent(this,CreateAccount_Activity.class);
			startActivity(i1);
			break;

		case R.id.login_access_button:
		{
			showLoadingDialog("Performing Access");
			goToTest = false;
			automaticLogin=false;
			performLoginRequest();
			break;
		}
		case R.id.login_test_button:
			Intent i3 = new Intent(this,Test_Activity.class);
			if(account!=null && system != null){
				i3.putExtra("account",account);
				i3.putExtra("system", system);
			}
			startActivity(i3);
			finish();
			break;

		case R.id.login_loginandtest_button:
		{
			goToTest = true;
			performLoginRequest();
			break;
		}
		}

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.login_menu_about:
			return menuAbout();
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	void onPerformRequest(LoginRequest req){
		//inizializzazione ...
		boolean connectionSuccess=false;
		boolean sendingSuccess=false;
		
		mm = new MessagingManager();
		connectionSuccess = mm.ConnectToServer(this); //mi connetto al server e mi iscrivo alle risposte
		sendingSuccess = mm.SendRequest(req, this); //invia una richiesta di info carta
		
		if(connectionSuccess==false || sendingSuccess==false){
			hideLoadingDialog(); //nasconde gli eventuai dialog
		}
		//qui sara necessario mostrare un popup di attesa, tipo "caricamento in corso" o roba simile
		//Toast.makeText(getApplicationContext(), "Request sent!", Toast.LENGTH_SHORT).show();
	}

	@Override
	void onResponseReceived(Object sender,TypedResponseReceivedEventArgs<ResponseWrapper> e) {
		ResponseBase respbase = e.getResponseMessage().getResponse();
		switch(respbase.getResponseType()){
		case Login:
			LoginResponse loginResp = (LoginResponse) respbase;

			if(loginResp.error==false){
				account.put(ACCOUNT_ID, loginResp.id);
				account.put(ACCOUNT_NAME, loginResp.name);
				account.put(ACCOUNT_EMAIL, loginResp.email);
				account.put(ACCOUNT_SURNAME, loginResp.surname);
				account.put(ACCOUNT_USERNAME, loginResp.username);
				account.put(ACCOUNT_LASTLOC, loginResp.lastLocation);
				account.put(ACCOUNT_PASSWORD, loginResp.password);
				account.put(ACCOUNT_CREATION, loginResp.creation);
				account.put(ACCOUNT_KEYPAIR, loginResp.keyPair);
				account.put(ACCOUNT_AVATAR, loginResp.avatar);

				system.put(SYSTEM_ALLOWLOCATION, 0 );


				//viene eseguito solo se non c'è stato un login automatico
				if (account.getAsBoolean("ACCOUNT_REMEMBER")==true && automaticLogin==false){
					//cancello tutte le info precedentemente salvate
					darco_db.deleteAll(TABLE_NAME_ACCOUNTS);
					darco_db.deleteAll(TABLE_NAME_SYSTEM);
					darco_db.deleteAll(TABLE_NAME_UNIQUECARDS);
					darco_db.deleteAll(TABLE_NAME_CARDS);
					darco_db.deleteAll(TABLE_NAME_CATEGORIES);

					darco_db.addAccount(loginResp.id, loginResp.email, loginResp.name, loginResp.surname, loginResp.username,
							loginResp.password, loginResp.lastLocation, loginResp.creation, loginResp.keyPair, loginResp.avatar);

					darco_db.addSystem("00000", loginResp.email, 0, 0);
					system.put(SYSTEM_ALLOWLOCATION, 0);
					system.put(SYSTEM_SAVEDACCOUNT, loginResp.email);

					Toast.makeText(this, "Account "+loginResp.email+" Saved!",Toast.LENGTH_SHORT).show();

				}
				
				Intent i2 = new Intent(this, (goToTest ? Test_Activity.class : Main_Activity.class));
				i2.putExtra("account",account);
				i2.putExtra("system", system);
				hideLoadingDialog();
				startActivity(i2);
				finish();
			}
			else{
				hideLoadingDialog();
				Toast.makeText(this, "Errore:"+loginResp.errorMessage, Toast.LENGTH_LONG).show();	
			}


			break;
		default:
			break;

		}
	}

}
